package edu.map.aamas.gui;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JFrame;
import javax.swing.JPanel;

import edu.map.aamas.gui.colormaps.ColorMap;
import edu.map.aamas.gui.colormaps.ColorMapFactory;
import edu.map.aamas.rnn.RNN;
import edu.map.aamas.rnn.RnnListener;

public class ConnectionMatrix extends JPanel implements RnnListener {

	private static final long serialVersionUID = 1L;
	
	private int lastHeight = 0, lastWidth = 0;
	private RNN rnr;
	private BufferedImage bi = null;
	private ColorMap cmap = ColorMapFactory.createBlueWhiteRedColormap();
	private Timer timer = null;
	
	public ConnectionMatrix(RNN rnr) {
		this.rnr = rnr;
		rnr.addRnrListener(this);
		setToolTipText("Random seed: "+rnr.randomSeed);
	}
	
	public void rnnRestarted(RNN rnr) {		
		bi = null;
		setToolTipText("Random seed: "+rnr.randomSeed);
		repaint();
	}
	
	public void rnnUpdated(RNN rnr) {
		repaint();
		if (timer == null && rnr.plasticity) {
			TimerTask tt = new TimerTask() {
				@Override
				public void run() {
					updateImage();
				}
			};
			timer = new Timer("connMatrix updater");
			timer.schedule(tt, 1000, 5000);
			timer.purge();
		}
		
		if (timer != null && !rnr.plasticity) {
			timer.cancel();
			timer.purge();
			timer = null;
		}
	}
	
	private void updateImage() {
		BufferedImage img = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
		double xInc = (double)getWidth() / (double)rnr.size;
		double yInc = (double)getHeight() / (double)rnr.size;
		//System.out.println("update");
		Graphics2D g2d = (Graphics2D) img.getGraphics();
		Rectangle2D.Double rect = new Rectangle2D.Double(0,0,xInc, yInc);
		for (int i = 0; i < rnr.size; i++) {
			g2d.setTransform(new AffineTransform());
			g2d.translate(0, yInc*i);
			for (int j = 0; j < rnr.size; j++) {
				double val = (rnr.M[i][j] + 1.0)/2;
				g2d.setColor(cmap.getColor(val));
				g2d.fill(rect);
				g2d.translate(xInc, 0);
			}
		}
		bi = img;
	}
	
	
	
	@Override
	public void paint(Graphics g) {
		super.paint(g);
		
		if (bi == null || lastHeight != getHeight() || lastWidth != getWidth()) {
			bi = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
			double xInc = (double)getWidth() / (double)rnr.size;
			double yInc = (double)getHeight() / (double)rnr.size;
			//System.out.println("update");
			Graphics2D g2d = (Graphics2D) bi.getGraphics();
			Rectangle2D.Double rect = new Rectangle2D.Double(0,0,xInc, yInc);
			for (int i = 0; i < rnr.size; i++) {
				g2d.setTransform(new AffineTransform());
				g2d.translate(0, yInc*i);
				for (int j = 0; j < rnr.size; j++) {
					double val = (rnr.M[i][j] + 1.0)/2;
					g2d.setColor(cmap.getColor(val));
					g2d.fill(rect);
					g2d.translate(xInc, 0);
				}
			}
		}
		g.drawImage(bi, 0, 0, this);
	}
	
	public static void main(String[] args) {
		JFrame test = new JFrame("test");
		RNN rnr = RNN.getInstance();
		ConnectionMatrix cm = new ConnectionMatrix(rnr);
		test.add(cm);
		test.setSize(400, 400);
		test.setVisible(true);
		test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
	}
	
	
}
